package iso8583

import (
	"bytes"
	"fmt"
	"strconv"

	"golang.org/x/text/encoding/simplifiedchinese"
)

//AlphanumericField 字符数字
type AlphanumericField struct {
	Field
}

// Str 打印字符串
func (alpha *AlphanumericField) Str() string {
	var buf bytes.Buffer
	buf.WriteString("AlphanumericField[\n\t")
	buf.WriteString(fmt.Sprintf("	name:%d \n\t", alpha.Name()))
	buf.WriteString(fmt.Sprintf("	type:%d \n\t", alpha.Field.Type))

	buf.WriteString(fmt.Sprintf("	dataStr:%s \n\t", alpha.ValueString()))
	buf.WriteString(fmt.Sprintf("	data:%v \n\t", alpha.Field.Data))
	buf.WriteString("]")
	return buf.String()
}

//NewAlphanumericField 创建数字字符域
func NewAlphanumericField(name int, typ int, len int) *AlphanumericField {
	return &AlphanumericField{
		Field: Field{
			Name:   name,
			Type:   typ,
			Len:    len,
			PadMod: RightPad,
		},
	}
}

//Name 获取名称
func (alpha *AlphanumericField) Name() int {
	return alpha.Field.Name
}

//ValueString 真值
func (alpha *AlphanumericField) ValueString() string {
	return alpha.Field.DataStr
}

//Format 格式化域更具情况填充域值
func (alpha *AlphanumericField) Format() []byte {
	if alpha.Field.Type == FIX {
		//如果是右靠齐就是填充左边
		l := alpha.Field.Len
		if alpha.PadMod == LeftPad {
			alpha.Field.Data = LeftPading(alpha.Field.Data, l, BLANK)
		} else if alpha.PadMod == RightPad {
			alpha.Field.Data = RightLading(alpha.Field.Data, l, BLANK)
		}
	}
	return alpha.Field.Data
}

//Parse 解析
func (alpha *AlphanumericField) Parse(b []byte, pos *Position) string {
	//data := alpha.Data;
	switch alpha.Type {
	case FIX:
		dist := make([]byte, alpha.Len)
		copy(dist, b[pos.Get():pos.Get()+alpha.Len])
		pos.Add(alpha.Len)
		alpha.Data = dist
		alpha.DataStr = string(alpha.Data)

	case LLVAR, LLLVAR:
		//获取2个字节的长度值
		len := alpha.Type
		size := b[pos.Get() : pos.Get()+len]
		pos.Add(len)
		if strLen, err := strconv.Atoi(string(size)); err == nil {
			dist := make([]byte, strLen)
			copy(dist, b[pos.Get():pos.Get()+strLen])
			pos.Add(strLen)
			alpha.Data = dist
			alpha.DataStr = string(alpha.Data)
		} else {
			fmt.Printf("解析域出现错误：%+v\n\t", err.Error())
		}
	}
	switch alpha.Field.Name {
	case 43:
		b := alpha.Field.Data
		reader, err := simplifiedchinese.GB18030.NewDecoder().Bytes(b)
		if err != nil {
			fmt.Println(err)
		} else {
			alpha.DataStr = string(reader)
		}

	default:

	}
	fmt.Printf("解析域（%d）完毕：%+v\n\t", alpha.Field.Name, alpha)
	return alpha.DataStr
}
func init() {
	Register(35, NewAlphanumericField(35, LLVAR, 39))     //域 35 第二磁道数据 z..37(LLVAR)，2个字节的长度值＋最大37个字节(字符)的第二磁道数据
	Register(36, NewAlphanumericField(36, LLLVAR, 107))   //域 36 第三磁道数据 z...104(LLLVAR)，3 个字节的长度值＋最大 104 个字节(字符)的第三磁道数据
	Register(37, NewAlphanumericField(37, FIX, 12))       //域 37 检索参考号 an12，12位定长的字母和数字字符
	Register(38, NewAlphanumericField(38, FIX, 6))        //域 38 授权标识应答码 an6，6位定长的字母、数字字符
	Register(39, NewAlphanumericField(39, FIX, 2))        //域 39 应答码 an2，2位定长的字母、数字字符
	Register(41, NewAlphanumericField(41, FIX, 8))        //域 41 受卡机终端标识码 ans8，8位定长的字母、数字和特殊字符
	Register(42, NewAlphanumericField(42, FIX, 15))       //域 42 受卡方标识码，受卡方的标识码，即商户代码。
	Register(44, NewAlphanumericField(44, LLVAR, 27))     //域 44 附加响应数据，ans..25(LLVAR)，2个字节的长度值＋最大25个字节(字母、数字和特殊字符)的附加响应数据
	Register(45, NewAlphanumericField(45, LLVAR, 78))     //域 45 第一磁道数据，z..76（LLVAR），2个字节的长度值＋最大76个字节（字符）的第一磁道数据
	Register(48, NewAlphanumericField(48, LLLVAR, 515))   //域 48 附加数据－私有 ansb...512(LLLVAR)，3个字节的长度值＋最大512个字节(字母、数字、特殊字符、二进制数)的私有附加数据
	Register(49, NewAlphanumericField(49, FIX, 3))        //域 49 交易货币代码 an3，3位定长的字母、数字字符
	Register(50, NewAlphanumericField(50, FIX, 3))        //域 50 清算货币代码 an3, 3位定长的字母、数字字符
	Register(51, NewAlphanumericField(51, FIX, 3))        //域 51 清算货币代码 an3, 3位定长的字母、数字字符
	Register(54, NewAlphanumericField(54, LLLVAR, 43))    //域 54 实际余额 an...040(LLLVAR)，3个字节的长度值＋最大40个字节(字母、数字字符)的实际余额
	Register(55, NewAlphanumericField(55, LLLVAR, 258))   //域 55 基于 UICS 借贷记标准的 IC卡数据域 ansb...255(LLLVAR)，3个字节的长度值＋最大255个字节的数据。
	Register(56, NewAlphanumericField(56, LLLVAR, 515))   //域 56 附加信息 ansb…512（LLLVAR），3字节长度值＋最大512个字节(字母、数字和特殊字符)的数据
	Register(57, NewAlphanumericField(57, LLLVAR, 103))   //域 57 附加交易信息 ansb…512（LLLVAR），ans...100(LLLVAR)，3个字节的长度值＋最大100个字节(字母、数字和特殊字符)的附加交易信息
	Register(59, NewAlphanumericField(59, LLLVAR, 603))   //域 59 明细查询数据 ans…600（LLLVAR），3个字节的长度值＋最大600个字节（字母、数字和特殊字符）的明细查询数
	Register(60, NewAlphanumericField(60, LLLVAR, 103))   //域 60 自定义域 ans..100(LLLVAR)，3个字节的长度值＋最大100个字节(字母、数字和特殊字符)的数据
	Register(62, NewAlphanumericField(62, LLLVAR, 203))   //域 62 交换中心数据 ans…200（LLLVAR），3字节长度值＋最多200个字节(字母、数字和特殊字符)的银联处理中心数据
	Register(63, NewAlphanumericField(63, LLLVAR, 515))   //域 63 金融网络数据 ans…200（LLLVAR），ansb…512（LLLVAR），3字节长度值＋最大512个字节(字母、数字和特殊字符)的金融网络数据
	Register(100, NewAlphanumericField(100, LLVAR, 13))   //域 100 接收机构标识码，an..11(LLVAR)，2个字节的长度值＋最大11个字节的接收机构标识码
	Register(102, NewAlphanumericField(102, LLVAR, 30))   //域 102 账户标识 1，ans..28(LLVAR)，2个字节的长度值＋最大28个字节（字母、数字和特殊字符）的账户标识
	Register(103, NewAlphanumericField(103, LLVAR, 30))   //域 103 账户标识 2，ans..28(LLVAR)，2个字节的长度值＋最大28个字节（字母、数字和特殊字符）的账户标识
	Register(104, NewAlphanumericField(104, LLLVAR, 515)) //域 104 附加信息，ansb…512（LLLVAR），3字节长度值＋最大512个字节(字母、数字和特殊字符)的数据
	Register(113, NewAlphanumericField(113, LLLVAR, 515)) //域 113 附加信息，ansb…512（LLLVAR），3字节长度值＋最大512个字节(字母、数字和特殊字符)的数据
	Register(116, NewAlphanumericField(116, LLLVAR, 515)) //域 116 附加信息，ansb…512（LLLVAR），3字节长度值＋最大512个字节(字母、数字和特殊字符)的数据
	Register(117, NewAlphanumericField(117, LLLVAR, 259)) //域 117 附加信息，ansb…256（LLLVAR），3字节长度值＋最大256个字节(字母、数字和特殊字符)的数据
	Register(121, NewAlphanumericField(117, LLLVAR, 103)) //域 121 CUPS 保留，ans...100(LLLVAR)，3个字节的长度值＋最大100个字节（数字、字母和特殊字符）的CUPS保留信息
	Register(122, NewAlphanumericField(122, LLLVAR, 103)) //域 122 受理方保留，ans...100(LLLVAR)，ans...100(LLLVAR)，3个字节的长度值＋最大100个字节（字母、数字和特殊字符）的受理方保留信息
	Register(123, NewAlphanumericField(123, LLLVAR, 103)) //域 123 发卡方保留，ans...100(LLLVAR)，3个字节的长度值＋最大100个字节（字母、数字和特殊字符）的发卡方保留信息
	//Register(125, NewAlphanumericField(125, LLLVAR, 259)) //域 125 附加信息，ansb…256（LLLVAR），3字节长度值＋最大256个字节(字母、数字和特殊字符)的数据
	Register(126, NewAlphanumericField(126, LLLVAR, 259)) //域 126 附加信息，ansb…256（LLLVAR），3字节长度值＋最大256个字节(字母、数字和特殊字符)的数据

}
